入门
shell脚本默认的【大家约定的并不是百分百】是.sh结尾的
而且脚本需要有执行权限+x
我们也可以通过sh [文件名] 来执行本文件;也是用sh命令来执行这个脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [hadoop@hadoop data]$ sh --help GNU bash, version 4.2.46(2)-release-(x86_64-redhat-linux-gnu) Usage: sh [GNU long option] [option] ... sh [GNU long option] [option] script-file ... GNU long options: --debug --debugger --dump-po-strings --dump-strings --help --init-file --login --noediting --noprofile --norc --posix --protected --rcfile --rpm-requires --restricted --verbose --version Shell options: -irsD or -c command or -O shopt_option (invocation only) -abefhkmnptuvxBCHP or -o option Type `sh -c "help set"' for more information about shell options. Type `sh -c help' for more information about shell builtin commands.
总结: 1.后缀是.sh 2.第一行的#!/bin/bash
假如使用sh命令执行脚本文件,可以没有+x 和 第一行解释器#!/bin/bash 假如不是使用sh命令,那么需要+x 且 #!/bin/bash
shell的debug 可以在#!/bin/bash 加上 -x 即 #!/bin/bash -x 来执行debuy 从上而下 一行行执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [hadoop@hadoop data]$ vim test.sh [hadoop@hadoop data]$ cat test.sh #!/bin/bash -x echo "hello world" ll pwd [hadoop@hadoop data]$ chmod +x test.sh [hadoop@hadoop data]$ ./test.sh + echo 'hello world' hello world + ll ./test.sh: line 3: ll: command not found + pwd /home/hadoop/data [hadoop@hadoop data]$
变量 1 2 3 4 5 6 7 8 9 10 11 [hadoop@hadoop data]$ ./test.sh hello world Thu Apr 11 19:03:19 CST 2019 [hadoop@hadoop data]$ cat test.sh #!/bin/bash WANG='hello world' DATE=`date` echo ${WANG} echo ${DATE} [hadoop@hadoop data]$
注意:变量全部用大写
静态变量 【可以没有引号;可以单引号和双引号】 K=V ‘V’ “V”
动态变量【反斜杠引号】【比如TEST=spark
echo ${TEST}指的是用户环境里的spark命令】[建议使用用户环境变量里的命令时候补全命令的路径(也就是安装目录下的bin目录下的此命令=全路径)] K=V
=前后不能有空格
引用:【可以有{}也可以没有{}中括号】 $KA 【这里的KA是一个变量】 ${K}A 【这里的K是一个变量;A就是字母A】
传递参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 [hadoop@hadoop data]$ cat test.sh #!/bin/bash echo $1 echo $2 echo "个数:$#" echo "参数作为一个长字符串:$*" echo "PID: $$" [hadoop@hadoop data]$ ./test.sh 个数:0 参数作为一个长字符串: PID: 10321 [hadoop@hadoop data]$ [hadoop@hadoop data]$ ./test.sh a b a b 个数:2 参数作为一个长字符串:a b PID: 10324 [hadoop@hadoop data]$
个数:0 参数作为一个长字符串: PID: 10321【shell脚本执行的那一刹那的pid;执行完毕后pid就消失了】
1、$1代表第一个参数 2、$2代表第二个参数 3、shell脚本传递参数按照空格来分割 4、$#代表的是参数的个数 5、$的 号代表把传递进来的参数作为长字符串输出
补充:PID: 10321如何确定已经消失
1 2 3 4 [hadoop@hadoop data]$ ps -ef|grep 10321 hadoop 10326 10162 0 19:18 pts/0 00:00:00 grep --color=auto 10321 [hadoop@hadoop data]$ ps -ef|grep 10321|grep -v grep [hadoop@hadoop data]$
可以看出10321是没有进程存在的;因为脚本执行完毕后pid就会消失。 第一次输出的hadoop 10326 10162 0 19:18 pts/0 00:00:00 grep –color=auto 10321是捕获的自己执行的10321并不是pid为10321的进程;加上|grep -v grep就会忽略捕获自己
数组 shell脚本里的数组只支持一维的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [hadoop@hadoop data]$ cat test.sh #!/bin/bash arr=(dingyi zhaoer zhangsan lisi wangwu) echo ${arr[@]} echo ${arr[*]} echo ${arr[4]} echo ${#arr[@]} [hadoop@hadoop data]$ ./test.sh dingyi zhaoer zhangsan lisi wangwu dingyi zhaoer zhangsan lisi wangwu wangwu 5 [hadoop@hadoop data]$
1、数组以空格分割的 2、@和*表示输出数组中所有元素 3、[4]表示第五个元素 5、#arr[@]表示数组的元素个数
if判断 1 2 3 4 5 6 7 8 9 10 11 12 13 [hadoop@hadoop data]$ cat test.sh #!/bin/bash A="abc" B="efgh" if [ "${a}" == "$b" ];then echo "==" else echo "!=" fi [hadoop@hadoop data]$ ./test.sh ==
这里的a,b都不存在所以都是空的;所以输出的是==
注意 ==前后有空格 [ $a == $b ]
启用debug’模式查看并修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 [hadoop@hadoop data]$ cat test.sh #!/bin/bash -x A="abc" B="efgh" if [ "${a}" == "$b" ];then echo "==" else echo "!=" fi [hadoop@hadoop data]$ ./test.sh + A=abc + B=efgh + '[' '' == '' ']' + echo == == [hadoop@hadoop data]$ 修改后 [hadoop@hadoop data]$ cat test.sh #!/bin/bash A="abc" B="efgh" if [ "${A}" == "$B" ];then echo "==" else echo "!=" fi [hadoop@hadoop data]$ ./test.sh !=
if elif else
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [hadoop@hadoop data]$ cat test.sh #!/bin/bash A="abc" B="efgh" if [ "${A}" == "$B" ];then echo "==" elif [ $A == "abc" ];then echo "abc here" else echo "!=" fi [hadoop@hadoop data]$ ./test.sh abc here
循环 let表示后面的值要进行运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 [hadoop@hadoop data]$ cat test.sh #!/bin/bash j=0 for x in 1 2 3 4 5 do echo $x let "j++" done echo $j echo "------------------" for ((i=1;i<5;i++)) do echo $i done echo "====================" x=1 y=1 while(($y<5)) do echo $y let "y++" let "x++" done echo "x: ${x}" [hadoop@hadoop data]$ ./test.sh 1 2 3 4 5 5 ------------------ 1 2 3 4 ==================== 1 2 3 4 x: 5 [hadoop@hadoop data]$
分割 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [hadoop@hadoop data]$ cat test.sh #!/bin/bash S="wangwu,zhangsan,lisi,dingyi" OLD_IFS="$IFS" IFS="," arr=($S) IFS="OLD_IFS" for x in ${arr[*]} do echo $x done [hadoop@hadoop data]$ ./test.sh wangwu zhangsan lisi dingyi [hadoop@hadoop data]$
其中
OLD_IFS=”$IFS” IFS=”,”【分隔符】 arr=($S)【数组】 IFS=”OLD_IFS”
是固定写法;将分割好的元素放入arr数组
awk命令 取数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 [hadoop@hadoop data]$ cat test.txt 1 2 3 4 5 6 7 8 9 打印第一列 [hadoop@hadoop data]$ cat test.txt |awk '{print $1}' 1 4 7 [hadoop@hadoop data]$ 打印前两列 [hadoop@hadoop data]$ cat test.txt |awk '{print $1 $2}' 12 45 78 [hadoop@hadoop data]$ cat test.txt |awk '{print $1,$2}' 1 2 4 5 7 8 有分隔符的打印 [hadoop@hadoop data]$ cat test.txt 1,2,3 4,5,6 7,8,9 [hadoop@hadoop data]$ [hadoop@hadoop data]$ cat test.txt |awk '{print $2}'【后面这个单引号不可以是双引号】 [hadoop@hadoop data]$ cat test.txt |awk -F "," '{print $2}' 2 5 8 打印行 [hadoop@hadoop data]$ cat test.txt |awk -F "," 'NR==1' 1,2,3 [hadoop@hadoop data]$ cat test.txt |awk -F "," 'NR==3' 7,8,9 [hadoop@hadoop data]$ cat test.txt |awk -F "," 'NR>1' 4,5,6 7,8,9 [hadoop@hadoop data]$ 打印大于第一行的行并第三列 [hadoop@hadoop data]$ cat test.txt |awk -F "," 'NR>1{ print $3 }' 6 9 [hadoop@hadoop data]$ 同等 [hadoop@hadoop data]$ awk -F "," 'NR>1{ print $3 }' test.txt 6 9 [hadoop@hadoop data]$ awk --help 【具体看命令帮助】
其中{print $1}表示打印第一列;{print $2}就是第二列;{print $0}是打印全部;
注意{print $1,$2}和{print $1 $2}表示第一和第二列;有逗号和没逗号是有区别的
sed命令 替换 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 [hadoop@hadoop data]$ vi test.log a b c 1 2 3 替换a为aa [hadoop@hadoop data]$ sed -i 's/a/aa/' test.log [hadoop@hadoop data]$ cat test.log aa b c 1 2 3 将aa替换为aa' [hadoop@hadoop data]$ sed -i "s/aa/aa'/" test.log [hadoop@hadoop data]$ cat test.log aa' b c 1 2 3 将aa'替换为bbb【将/换为?用是一样的】 [hadoop@hadoop data]$ sed -i "s?aa'?bbb?" test.log [hadoop@hadoop data]$ cat test.log bbb b c 1 2 3 全局替换 g表示全局global [hadoop@hadoop data]$ sed -i "s/b/w/g" test.log [hadoop@hadoop data]$ cat test.log www w c 1 2 3 每行的行首前面加uuu [hadoop@hadoop data]$ sed -i "s/^/uuu&/g" test.log [hadoop@hadoop data]$ cat test.log uuuwww w c uuu1 2 3 每行行尾后面加uuu [hadoop@hadoop data]$ sed -i "s/$/&uuu/g" test.log [hadoop@hadoop data]$ cat test.log uuuwww w cuuu uuu1 2 3uuu [hadoop@hadoop data]$
补充 case in 判断uname是否是以CYGWIN*) 右括号结尾的
1 2 3 4 cygwin=false case "$(uname)" in CYGWIN*) cygwin=true;; esac
-z 判断字符串长度是否为0
1 2 3 4 5 6 7 teacher="wuwang" if [ -z "${teacher}" ]; then echo "Jepson" else { echo ${teacher} } fi
1 2 3 home=`cd (dirname "$0");pwd` echo ${home} #结果是 当前目录
$@
1 2 3 4 5 6 7 function main() { echo "input params is:"$@ } main "$@" #运行test.sh后面跟输入 xx yy zz #输出结果 xx yy zz
exec 执行后面的语句
1 exec "${SPARK_HOME}"/bin/...